package com.yuanxin.track;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.sinooceanland.commonutils.DeviceUtil;
import com.yuanxin.track.dbTables.AnyTrackCacheModel;
import com.yuanxin.track.dbTables.AnyTrackCacheModelDao;
import com.yuanxin.track.dbTables.AnyTrackUploadNewModel;
import com.yuanxin.track.dbTables.DaoMaster;
import com.yuanxin.track.dbTables.DaoSession;
import com.yuanxin.track.dbTables.UserActiveLogModel;
import com.yuanxin.track.dbTables.UserLoginLogModel;
import com.yuanxin.track.dbTables.UserLoginLogModelDao;


import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.query.WhereCondition;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;

/**
 * 用户行为分析原生模块
 */
public class TrackModule extends ReactContextBaseJavaModule {

    private static final String TAG = TrackModule.class.getSimpleName();

    private static final String REACT_MODULE_NAME = "YuanXinTrack";


    private String appID;
    private DaoSession daoSession;
    private ReactApplicationContext reactApplicationContext;
    /**
     * 登录日志
     */
    UserLoginLogModel loginLogBean;
    String deviceID;

    public TrackModule(ReactApplicationContext reactContext) {
        super(reactContext);
        reactApplicationContext=reactContext;
        try {
            deviceID = DeviceUtil.getDeviceID(getReactApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }
        appID = BuildConfig.AppID;

        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(getReactApplicationContext(), "trackDb");
        Database db = helper.getWritableDb();
        daoSession = new DaoMaster(db).newSession();

        DataUploadManager.init(daoSession);
        DataUploadManager.start();
        AnyTrackUploadManager.init(daoSession);
        saveBeforeAnyTrack();
        AnyTrackUploadManager.start();

    }

    /**
     * 保存上一次退出登录时留存的缓存数据，并上传
     */
    private void saveBeforeAnyTrack() {
        List<AnyTrackCacheModel> groupList = daoSession.getAnyTrackCacheModelDao().queryBuilder().where(new WhereCondition.StringCondition(" 1=1 GROUP BY " + AnyTrackCacheModelDao.Properties.SendUserId.columnName + ","
                + AnyTrackCacheModelDao.Properties.CategoryKey.columnName)).build().list();
        for (AnyTrackCacheModel item : groupList) {
            List<AnyTrackCacheModel> list = daoSession.getAnyTrackCacheModelDao().queryBuilder()
                    .where(AnyTrackCacheModelDao.Properties.SendUserId.eq(item.getSendUserId()),
                            AnyTrackCacheModelDao.Properties.CategoryKey.eq(item.getCategoryKey()))
                    .build().list();
            if (list != null) {
                for (int i = 0; i < list.size(); i += 5) {
                    saveAnyTrack(list.subList(i, i + 5 >= list.size() ? list.size() : i + 5), item.getSendUserId());
                }
            }

        }
    }


    @Override
    public String getName() {
        return REACT_MODULE_NAME;
    }


    /**
     * 用户行为日志记录
     *
     * @param map
     * @param promise
     */
    @ReactMethod
    public void recordTrackLog(ReadableMap map, Promise promise) {
        Log.d(TAG, "记录用户行为日志");
        if (map == null) {
            promise.reject("error", "args is null");
            return;
        }
        UserActiveLogModel trackLogBean = new UserActiveLogModel();
        if (map.hasKey("id")) {
            trackLogBean.setId(map.getString("id"));
        } else {
            promise.reject("error", "id is null");
            return;
        }
        if (map.hasKey("eventType")) {
            trackLogBean.setEventType(map.getString("eventType"));
        } else {
            promise.reject("error", "eventType is null");
            return;
        }
        if (map.hasKey("eventName")) {
            trackLogBean.setEventName(map.getString("eventName"));
        } else {
            promise.reject("error", "eventName is null");
            return;
        }
        if (map.hasKey("eventTime")) {
            String date = map.getString("eventTime");
            if (date == null || date.equals("")) {
                promise.reject("error", "eventTime is null");
                return;
            }
            trackLogBean.setEventTime(date);
        } else {
            promise.reject("error", "eventTime is null");
            return;
        }
        if (map.hasKey("eventData")) {
            trackLogBean.setEventData(new Gson().toJson(map.getMap("eventData").toHashMap()));
        }
        if (map.hasKey("logLot")) {
            trackLogBean.setLogLot(map.getString("logLot"));
        }
        trackLogBean.setAppID(appID);

        if (loginLogBean == null) {
            List<UserLoginLogModel> list = daoSession.getUserLoginLogModelDao()
                    .queryBuilder().orderDesc(UserLoginLogModelDao.Properties.LoginTime).list();
            if (list != null && list.size() > 0) {
                loginLogBean = list.get(0);
            }
        }
        if (loginLogBean == null) {
            return;
        }
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//        if (!loginLogBean.getLoginTime().substring(0, 10).equals(simpleDateFormat.format(new Date()))) {
//            loginLogBean.setId(UUID.randomUUID().toString());
//            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            loginLogBean.setLoginTime(simpleDateFormat.format(new Date()));
//            daoSession.getUserLoginLogModelDao().insert(loginLogBean);
//            // 立即上传一下登录日志
//            DataUploadManager.start();
//        }

        trackLogBean.setUserID(loginLogBean.getUserID());
        trackLogBean.setLoginId(loginLogBean.getId());

//         Log.d(TAG, "save Track : " + trackLogBean.toString());

        if (daoSession.getUserActiveLogModelDao().insert(trackLogBean) > 0) {
            trackLogCount++;
            promise.resolve("save success");
        } else {
            promise.reject("error", "save fail");
        }
//         Log.d(TAG, "trackLogCount :" + trackLogCount);
        if (trackLogCount >= 5) {
            trackLogCount = 0;
            DataUploadManager.start();
        }
    }

    private int trackLogCount = 0;

    /**
     * 用户登录日志记录
     *
     * @param map
     * @param promise
     */
    @ReactMethod
    public void recordLoginLog(ReadableMap map, Promise promise) {
        Log.d(TAG, "记录用户登录日志");


        if (map == null) {
            promise.reject("error", "args is null");
            return;
        }
        loginLogBean = new UserLoginLogModel();
        if (map.hasKey("id")) {
            loginLogBean.setId(map.getString("id"));
        } else {
            promise.reject("error", "id is null");
            return;
        }
        if (map.hasKey("userID")) {
            loginLogBean.setUserID(map.getString("userID"));
        } else {
            promise.reject("error", "userID is null");
            return;
        }
        if (map.hasKey("loginType")) {
            loginLogBean.setLoginType(map.getString("loginType"));
        } else {
            promise.reject("error", "loginType is null");
            return;
        }

        if (map.hasKey("loginTime")) {
            loginLogBean.setLoginTime(map.getString("loginTime"));
        } else {
            promise.reject("error", "loginTime is null");
            return;
        }
        if (map.hasKey("logLot")) {
            loginLogBean.setLogLot(map.getString("logLot"));
        }
        loginLogBean.setDeviceType("ANDROID");
        loginLogBean.setDeviceID(deviceID);
        loginLogBean.setSystemVersion(android.os.Build.VERSION.RELEASE);
        loginLogBean.setDeviceBrands(android.os.Build.BRAND.toUpperCase());//全部转为大写
        loginLogBean.setDeviceModel(android.os.Build.MODEL.toUpperCase());//全部转为大写
        loginLogBean.setDeviceLanguage(Locale.getDefault().getLanguage());
        loginLogBean.setTimeZone(TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT));
        // 获取packagemanager的实例
        PackageManager packageManager = getReactApplicationContext().getPackageManager();
        // getPackageName()是你当前类的包名，0代表是获取版本信息
        PackageInfo packInfo = null;
        try {
            packInfo = packageManager.getPackageInfo(getReactApplicationContext().getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        loginLogBean.setAppVersion(packInfo != null ? packInfo.versionName : "");
        loginLogBean.setAppID(appID);
        Log.d(TAG, "save Login : " + loginLogBean.toString());
        //保存登录日志
        if (daoSession.getUserLoginLogModelDao().insert(loginLogBean) > 0) {
            Log.d(TAG, "save Login success");
            promise.resolve("save success");
        } else {
            Log.d(TAG, "save Login fail");
            promise.reject("error", "save fail");
        }
        DataUploadManager.start();

    }


    @ReactMethod
    public void recordAnyTrackLog(ReadableMap map, Promise promise) {
        Log.d(TAG, "调用recordAnyTrackLog");
        if (map == null) {
            promise.reject("error", "args is null");
            return;
        }
        if (!map.hasKey("categoryKey")) {
            promise.reject("error", "缺少参数：categoryKey");
            return;
        }
        if (!map.hasKey("sendUserId")) {
            promise.reject("error", "缺少参数：sendUserId");
            return;
        }

        AnyTrackCacheModel anyTrackCacheModel = new AnyTrackCacheModel();
        anyTrackCacheModel.setSendUserId(map.getString("sendUserId"));
        anyTrackCacheModel.setCategoryKey(map.getString("categoryKey"));

        anyTrackCacheModel.setAny(new Gson().toJson(map.toHashMap()));

        daoSession.getAnyTrackCacheModelDao().insert(anyTrackCacheModel);


        List<AnyTrackCacheModel> list = daoSession.getAnyTrackCacheModelDao().queryBuilder()
                .where(AnyTrackCacheModelDao.Properties.SendUserId.eq(map.getString("sendUserId")),
                        AnyTrackCacheModelDao.Properties.CategoryKey.eq(map.getString("categoryKey")))
                .build().list();
        if (list != null && list.size() >= 5) {//数据满5条，获取设备信息，存入Upload表
            saveAnyTrack(list.subList(0, 4), map.getString("sendUserId"));
            AnyTrackUploadManager.start();
        }
        promise.resolve("save success！");
    }

    private void saveAnyTrack(List<AnyTrackCacheModel> list, String sendUserId) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("appID", BuildConfig.AppID);
        jsonObject.addProperty("appVersion", BuildConfig.AndroidVersionName);
        jsonObject.addProperty("deviceBrands", android.os.Build.BRAND.toUpperCase());
        jsonObject.addProperty("deviceID", deviceID);
        jsonObject.addProperty("deviceLanguage", Locale.getDefault().getLanguage());
        jsonObject.addProperty("deviceModel", android.os.Build.MODEL.toUpperCase());
        jsonObject.addProperty("deviceType", "ANDROID");
        jsonObject.addProperty("sendUserId", sendUserId);
        jsonObject.addProperty("systemVersion", android.os.Build.VERSION.RELEASE);

        JsonArray jsonArray = new JsonArray();
        Gson gson = new Gson();
        for (AnyTrackCacheModel item : list) {
            jsonArray.add(gson.fromJson(item.getAny(), JsonObject.class));
        }
        jsonObject.add("logs", jsonArray);
        Log.d(TAG, jsonObject.toString());

        AnyTrackUploadNewModel anyTrackUploadModel = new AnyTrackUploadNewModel();
        anyTrackUploadModel.setId(UUID.randomUUID().toString());
        anyTrackUploadModel.setUploadJson(jsonObject.toString());

        //避免异常导致崩溃
        try {
            daoSession.getAnyTrackUploadNewModelDao().insert(anyTrackUploadModel);
            daoSession.getAnyTrackCacheModelDao().deleteInTx(list);
        } catch (DaoException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置当前app的状态
     * @param isFront
     */
    @ReactMethod
    public void setAppPageStatus(boolean isFront){
        if(reactApplicationContext!=null){
            Log.e("MainApplication","setAppPageStatus=="+isFront);
            WritableMap params = Arguments.createMap();
            if(isFront){
                params.putString("appStatus","active");
            }else {
                params.putString("appStatus","background");
            }
            reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit("appCurrentStatus",params);
        }
    }
}
